﻿using UnityEngine;
using System.Collections;
using Game.Global.GameCenter;
using System.Collections.Generic;

namespace Game.Global.GameCenter
{

    /// <summary>
    /// 对成就进行管理的管理器，不同的平台的成就/排名系统等，可对此管理器所掌控的数据进行监听设置
    /// </summary>
    public class AchievementManager
    {
        const string C_ACHIEVEMENT_KEY = "_ACHIEVEMENT_PREFS";

        static AchievementManager _instance;

        /// <summary>
        /// 当某个成就达成时的回调
        /// </summary>
        event System.Func<AchievementData, bool> cb_onGoalAchieved;
        //当更新某个成就点数时（如果返回false，代表更新不成功，则需要重新更新）
        event System.Func<AchievementData, bool> cb_onAddAchievementData;

        //TODO:如果后期要通用，则考虑用String,Data的方式，存取对应的Achievement；设置ID等
        Dictionary<string, AchievementData> m_dictAchievementData;
        //---------------------------------------------------------------------------
        //                    Public area
        //---------------------------------------------------------------------------
        #region Public area

        /// <summary>
        /// 单例
        /// </summary>
        public static AchievementManager instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new AchievementManager();
                }
                return _instance;
            }
        }

        /// <summary>
        /// 当某个成就达成时的回调设定：
        /// </summary>
        /// <param name="onAchievedGoal">当达成时的回调，该方法需要返回是否成功发生回调，否则，会在特定时间之后被重新调用</param>
        /// <param name="onUpdateAchievement">当更新成就时的回调，该方法需要返回是否成功发生回调，否则，会在特定时间之后被重新调用</param>
        public void AddListener(System.Func<AchievementData, bool> onUpdateAchievement, System.Func<AchievementData, bool> onAchievedGoal)
        {
            cb_onGoalAchieved += onAchievedGoal;
            cb_onAddAchievementData += onUpdateAchievement;
        }

        /// <summary>
        /// 获得某成就当前的进度数目
        /// </summary>
        /// <returns></returns>
        public int GetAchievementProgress(string achievementType)
        {
            return m_dictAchievementData[achievementType].CurrAchiPoints;
        }

        /// <summary>
        /// 增加成就点数，如果达成则回调
        /// </summary>
        /// <param name="achievementId"></param>
        /// <param name="val"></param>
        public void AddAchievementPoint(string achievementId, int val)
        {
            var achievementData = m_dictAchievementData[achievementId];
            //如果之前未达成成就，且此处满足成就
            if (achievementData.IsAchieved == false
                && achievementData.AddAchiPointGot(val))
            {
                //回调：
                cb_onGoalAchieved(achievementData);
            }

            cb_onAddAchievementData(achievementData);
        }

        /// <summary>
        /// 增加成就点数，如果达成则回调
        /// </summary>
        public void AddAchievementPoint(System.Enum enumType, int val = 1)
        {
            AddAchievementPoint(enumType.ToString(), val);
        }

        //设置成就数据（外部初始化）
        internal void SetAchievementData(AchievementData[] datas)
        {
            m_dictAchievementData = new Dictionary<string, AchievementData>();

            AchievementData currData;
            for (int i = 0; i < datas.Length; i++)
            {
                currData = datas[i];
                m_dictAchievementData[currData.AchievementId] = currData;
            }
        }

        //获得成就数据（用于外部存储）
        internal AchievementData[] ToAchievementData()
        {
            if (m_dictAchievementData == null)
            {
                return null;
            }

            AchievementData[] result = new AchievementData[m_dictAchievementData.Count];
            int id = 0;
            foreach (var item in m_dictAchievementData)
            {
                result[id++] = item.Value;
            }

            return result;
        }

        #endregion

        //---------------------------------------------------------------------------
        //                    Private area
        //---------------------------------------------------------------------------
        #region Private area
        /// <summary>
        /// 构造函数，初始化时即读取数据，且不允许外部实例化
        /// </summary>
        private AchievementManager()
        {

        }

        ///// <summary>
        ///// Read the achievement data from PlayerPref 
        ///// </summary>
        ///// <returns>Success or not</returns>
        //private  bool ReadAchievementDatas(int acvmCount)
        //{
        //    //--get the value set:
        //    string valueSet = PlayerPrefs.GetString(C_ACHIEVEMENT_KEY, null);

        //    if (valueSet == null || valueSet.Equals(""))
        //    {
        //        return false;
        //    }

        //    //--try to get the value string:
        //    string[] valueStrs = valueSet.Split(';');

        //    //CHeck:
        //    if (acvmCount != valueStrs.Length)
        //    {
        //        Debug.LogError("Illegal length of achievement.Check your setting...");
        //        return false;
        //    }

        //    int val;
        //    //--Try to pharse
        //    for (int i = 0; i < acvmCount; i++)
        //    {
        //        //Is achieved marked
        //        if (valueStrs[i].Contains(" "))
        //        {
        //            //g_achieveDatas[i].isAchieved = true;
        //        }

        //        //Parse value:
        //        int.TryParse(valueStrs[i], out val);

        //        //--set it to achievement datas:
        //        g_achieveDatas[i].CurrAchiPoints = val;
        //    }

        //    return true;
        //}


        ////--Save & read--
        //public void SaveAchievementDatas()
        //{
        //    int achieveCount;
        //    //Check null or zero length:
        //    if (g_achieveDatas == null ||
        //        (achieveCount = g_achieveDatas.Length) <= 0)
        //        return;


        //    System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder();

        //    //Get the val string:
        //    for (int i = 0; i < achieveCount; i++)
        //    {
        //        stringBuilder.Append(g_achieveDatas[i]);
        //        if (g_achieveDatas[i].IsAchieved)
        //        {
        //            //mark if is achieved:
        //            stringBuilder.Append(" ");
        //        }

        //        if (i != achieveCount - 1)
        //        {
        //            //Add a split char:
        //            stringBuilder.Append(';');
        //        }

        //    }

        //    //--Save to prefs:
        //    PlayerPrefs.SetString(C_ACHIEVEMENT_KEY, stringBuilder.ToString());
        //    PlayerPrefs.Save();
        //}

        #endregion
    }
}